/*
 * Copyright (C) 2018 INFORMATION SERVICES INTERNATIONAL - DENTSU, LTD. All Rights Reserved.
 *
 * Unless you have purchased a commercial license,
 * the following license terms apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */

package org.iplass.adminconsole.client.metadata.ui.entity.viewcontrol;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.iplass.adminconsole.client.base.ui.widget.MtpDialog;
import org.iplass.adminconsole.client.base.ui.widget.form.MtpForm;
import org.iplass.adminconsole.client.base.ui.widget.form.MtpTextItem;
import org.iplass.adminconsole.client.base.util.SmartGWTUtil;
import org.iplass.adminconsole.client.metadata.data.auth.RoleDS;
import org.iplass.mtp.view.generic.ViewControlSetting;

import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.MultipleAppearance;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.grid.HeaderSpan;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridEditorContext;
import com.smartgwt.client.widgets.grid.ListGridEditorCustomizer;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;

public class ViewControlSettingListGrid extends ListGrid {

	public ViewControlSettingListGrid() {
		setWidth100();
		setHeight(1);

		setShowAllColumns(true);
		setShowAllRecords(true);

		setBodyOverflow(Overflow.VISIBLE);
		setOverflow(Overflow.VISIBLE);

		setCanFreezeFields(false);
		setCanGroupBy(false);
		setCanPickFields(false);
		setCanSort(false);
		setCanAutoFitFields(false);

		setCanEdit(true);

		HeaderSpan detailHeader = new HeaderSpan("DetailView Layout", new String[] {
			ViewControlSettingListGridRecord.EXISTDVIEW,
			ViewControlSettingListGridRecord.AGDVIEW
		});
		HeaderSpan searchHeader = new HeaderSpan("SearchView Layout", new String[] {
			ViewControlSettingListGridRecord.EXISTSVIEW,
			ViewControlSettingListGridRecord.AGSVIEW
		});
		HeaderSpan bulkHeader = new HeaderSpan("BulkView Layout", new String[] {
			ViewControlSettingListGridRecord.EXISTBVIEW,
			ViewControlSettingListGridRecord.AGBVIEW
		});

		setHeaderSpans(detailHeader, searchHeader, bulkHeader);
		setHeaderHeight(44);

		// 各フィールド初期化
		ListGridField displayNameField = new ListGridField(ViewControlSettingListGridRecord.DISPLAY_NAME, "View Name");
		displayNameField.setWidth(100);
		displayNameField.setCanEdit(false);

		ListGridField definedDvField = new ListGridField(ViewControlSettingListGridRecord.EXISTDVIEW, "Defined");
		definedDvField.setWidth(100);
		definedDvField.setCanEdit(false);
		definedDvField.setType(ListGridFieldType.BOOLEAN);

		ListGridField autogenerateDvField = new ListGridField(ViewControlSettingListGridRecord.AGDVIEW, "AutoGenerate");
		autogenerateDvField.setWidth(100);
		autogenerateDvField.setType(ListGridFieldType.BOOLEAN);

		ListGridField definedSvField = new ListGridField(ViewControlSettingListGridRecord.EXISTSVIEW, "Defined");
		definedSvField.setWidth(100);
		definedSvField.setCanEdit(false);
		definedSvField.setType(ListGridFieldType.BOOLEAN);

		ListGridField autogenerateSvField = new ListGridField(ViewControlSettingListGridRecord.AGSVIEW, "AutoGenerate");
		autogenerateSvField.setWidth(100);
		autogenerateSvField.setType(ListGridFieldType.BOOLEAN);

		ListGridField definedBvField = new ListGridField(ViewControlSettingListGridRecord.EXISTBVIEW, "Defined");
		definedBvField.setWidth(100);
		definedBvField.setCanEdit(false);
		definedBvField.setType(ListGridFieldType.BOOLEAN);

		ListGridField autogenerateBvField = new ListGridField(ViewControlSettingListGridRecord.AGBVIEW, "AutoGenerate");
		autogenerateBvField.setWidth(100);
		autogenerateBvField.setType(ListGridFieldType.BOOLEAN);

		ListGridField permitRolesField = new ListGridField(ViewControlSettingListGridRecord.PERMIT_ROLES, "Permit Roles");
//		permitRolesField.setWidth(250);

		// 各フィールドをListGridに設定
		setFields(displayNameField, definedDvField, autogenerateDvField, definedSvField, autogenerateSvField, definedBvField, autogenerateBvField, permitRolesField);

		setEditorCustomizer(new ListGridEditorCustomizer() {

			@Override
			public FormItem getEditor(ListGridEditorContext context) {
				ListGridField field = context.getEditField();
				if (ViewControlSettingListGridRecord.PERMIT_ROLES.equals( field.getName())) {
					SelectItem fieldItem = new SelectItem();
					fieldItem.setShowTitle(false);
					fieldItem.setMultiple(true);
					fieldItem.setMultipleAppearance(MultipleAppearance.PICKLIST);
					RoleDS.setDataSource(fieldItem);
					return fieldItem;
				}
				return context.getDefaultProperties();
			}
		});
	}

	public void showAddViewControlSettingDialog() {
		ViewControlSettingCreateDialog dialog = new ViewControlSettingCreateDialog();
		dialog.show();
	}

	public void setDefinition(List<ViewControlSetting> settings, List<String> detailViewNames, List<String> searchViewNames, List<String> bulkViewNames) {
		if (settings == null) return;

		Map<String, ViewControlSettingListGridRecord> viewMap = new HashMap<>();

		for (ViewControlSetting setting : settings) {
			ViewControlSettingListGridRecord record = new ViewControlSettingListGridRecord();

			if (setting.getName() == null || setting.getName().isEmpty()) {
				record.setSettingName("");
				record.setDisplayName("default");
			} else {
				record.setSettingName(setting.getName());
				record.setDisplayName(setting.getName());
			}

			record.setAutoGenerateDetailView(setting.isAutoGenerateDetailView());
			record.setAutoGenerateSearchView(setting.isAutoGenerateSearchView());
			record.setAutoGenerateBulkView(setting.isAutoGenerateBulkView());

			String[] permitRoles = null;
			if (setting.getPermitRoles() != null && !setting.getPermitRoles().isEmpty()) {
				permitRoles = setting.getPermitRoles().split(",");
			}
			record.setPermitRoles(permitRoles);

			viewMap.put(setting.getName(), record);
		}

		for (String view : detailViewNames) {
			ViewControlSettingListGridRecord record = null;
			if (viewMap.containsKey(view)) {
				record = viewMap.get(view);
			} else {
				record = new ViewControlSettingListGridRecord();
				if (view == null || view.isEmpty()) {
					record.setSettingName("");
					record.setDisplayName("default");
				} else {
					record.setSettingName(view);
					record.setDisplayName(view);
				}
				viewMap.put(view, record);
			}

			record.setExistDetailView(true);
		}

		for (String view : searchViewNames) {
			ViewControlSettingListGridRecord record = null;
			if (viewMap.containsKey(view)) {
				record = viewMap.get(view);
			} else {
				record = new ViewControlSettingListGridRecord();
				if (view == null || view.isEmpty()) {
					record.setSettingName("");
					record.setDisplayName("default");
				} else {
					record.setSettingName(view);
					record.setDisplayName(view);
				}
				viewMap.put(view, record);
			}
			record.setExistSearchView(true);
		}

		for (String view : bulkViewNames) {
			ViewControlSettingListGridRecord record = null;
			if (viewMap.containsKey(view)) {
				record = viewMap.get(view);
			} else {
				record = new ViewControlSettingListGridRecord();
				if (view == null || view.isEmpty()) {
					record.setSettingName("");
					record.setDisplayName("default");
				} else {
					record.setSettingName(view);
					record.setDisplayName(view);
				}
				viewMap.put(view, record);
			}
			record.setExistBulkView(true);
		}

		List<ViewControlSettingListGridRecord> records = viewMap.values().stream().collect(Collectors.toList());
		records.sort(Comparator.comparing(ViewControlSettingListGridRecord::getSettingName, Comparator.nullsFirst(Comparator.naturalOrder())));

		setData(records.toArray(new ViewControlSettingListGridRecord[]{}));
	}

	public List<ViewControlSetting> getEditDefinition() {
		List<ViewControlSetting> ret = new ArrayList<>();

		ListGridRecord[] records = getRecords();
		for (ListGridRecord record : records) {
			ViewControlSettingListGridRecord _record = (ViewControlSettingListGridRecord) record;
			ViewControlSetting setting = new ViewControlSetting();
			setting.setName(_record.getSettingName());
			setting.setAutoGenerateDetailView(_record.isAutoGenerateDetailView());
			setting.setAutoGenerateSearchView(_record.isAutoGenerateSearchView());
			setting.setAutoGenerateBulkView(_record.isAutoGenerateBulkView());

			String[] permitRoles = _record.getPermitRoles();
			if (permitRoles != null && permitRoles.length > 0) {
				StringBuilder sb = new StringBuilder();
				for (String permitRole : permitRoles) {
					if (sb.length() > 0) sb.append(",");
					sb.append(permitRole);
				}
				setting.setPermitRoles(sb.toString());
			}

			ret.add(setting);
		}
		return ret;
	}

	private class ViewControlSettingCreateDialog extends MtpDialog {

		private DynamicForm form;

		private TextItem nameField;

		public ViewControlSettingCreateDialog() {

			setHeight(140);
			setTitle("Add ViewControl Setting");
			centerInPage();

			form = new MtpForm();

			nameField = new MtpTextItem("name", "View Name");
			SmartGWTUtil.setRequired(nameField);

			form.setFields(nameField);

			container.addMember(form);

			IButton ok = new IButton("OK");
			ok.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					if (!form.validate()) {
						return;
					}

					String viewName = SmartGWTUtil.getStringValue(nameField);
					for (ListGridRecord r : getRecords()) {
						ViewControlSettingListGridRecord gridRecord = (ViewControlSettingListGridRecord) r;
						if (gridRecord.getSettingName().equals(viewName)) {
							//allready exist
							SC.say(viewName + " is allready exist.");
							return;
						}
					}

					updateRecordData(viewName);
					destroy();
				}
			});
			IButton cancel = new IButton("Cancel");
			cancel.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					destroy();
				}
			});

			footer.setMembers(ok, cancel);
		}

		private void updateRecordData(String viewName) {
			ViewControlSettingListGridRecord record = new ViewControlSettingListGridRecord();
			record.setSettingName(viewName);
			record.setDisplayName(viewName);

			addData(record);
			updateData(record);
			refreshFields();
		}
	}
}
